package main

import (
	"fmt"
	"strings"
)

func main() {
	maps()            //map映射
	multi_map()       //映射字面量
	change_map()      //修改映射
	WordCount("test") //练习：映射
}

// map 映射将键映射到值。类型随意
// 映射的零值为 nil 。nil 映射既没有键，也不能添加键。
// make 函数会返回给定类型的映射，并将其初始化备用。
func maps() {
	type Vertex struct {
		lat, long float64
	}

	var m map[string]Vertex

	m = make(map[string]Vertex)
	m["erxat"] = Vertex{
		40.15548, -99.2323,
	}

	fmt.Println(m["erxat"])
}

// 映射的字面量和结构体类似，只不过必须有键名。
// 若顶层类型只是一个类型名，那么你可以在字面量的元素中省略它。
func multi_map() {
	type Vertex struct {
		lat, long float64
	}

	var a = map[string]Vertex{
		"jack": Vertex{
			32.134, 43.1123,
		},
		"tom": Vertex{
			2445, -2222,
		},
	}
	fmt.Println(a)

	var b = map[string]Vertex{
		"first":  {33.113, 5454},
		"nother": {2124, 322},
	}
	fmt.Println(b)
}

// 插入或修改元素
func change_map() {
	m := make(map[string]int)

	m["ans"] = 43
	fmt.Println("值:", m["答案"])

	m["ans"] = 88
	fmt.Println("值:", m["ans"])

	//获取元素,若 key 不在映射中，则 elem 是该映射元素类型的零值。
	elem := m["ans"]
	fmt.Println("值:", elem)

	//通过双赋值检测某个键是否存在：
	v, ok := m["ans"]
	fmt.Println(v, "是否存在:", ok)

	//删除元素
	delete(m, "ans")
	//删除后需重新获取元素来更新
	v, ok = m["ans"]
	fmt.Println(v, "是否存在:", ok)

}

// 实现 WordCount。它应当返回一个映射，其中包含字符串 s 中每个“单词”的个数
func WordCount(str string) map[string]int {
	m := make(map[string]int)
	slice := strings.Fields(str)

	for _, v := range slice {
		m[v] += 1
	}

	return m
}
